﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace RESTfulExtension
{
    //https://smellegantcode.wordpress.com/2008/12/10/optimizing-aggregate-for-string-concatenation/
    public static class EnumerableExtensions
    {
        private static string Oggregate(this IEnumerable<string> source, string delimiter)
        {
            var builder = new StringBuilder();

            builder.Append(source.First());

            foreach (var s in source.Skip(1))
            {
                builder.Append(delimiter);
                builder.Append(s);
            }

            return builder.ToString();
        }


        public static string Aggregate(this IEnumerable<string> source, Expression<Func<string, string, string>> func)
        {
            BinaryExpression root = func.Body as BinaryExpression;
            if (root?.NodeType == ExpressionType.Add)
            {
                BinaryExpression left = root.Left as BinaryExpression;
                if (left?.NodeType == ExpressionType.Add)
                {
                    ParameterExpression leftLeft =
                        left.Left as ParameterExpression;

                    if (leftLeft != null)
                    {
                        ConstantExpression leftRight =
                            left.Right as ConstantExpression;

                        if (leftRight != null)
                        {
                            ParameterExpression right =
                                root.Right as ParameterExpression;

                            if (right != null)
                            {
                                if ((leftLeft.Name == func.Parameters[0].Name)
                                    && (right.Name == func.Parameters[1].Name))
                                    return source.Oggregate(
                                        (string)leftRight.Value);
                            }
                        }
                    }
                }
            }

            return source.Aggregate(func.Compile());
        }

    }
}
